home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / docs / Cache_Lite / TODO < prev   
Encoding:
Text File  |  2004-10-01  |  7.1 KB  |  213 lines

  1.  
  2. Patrick O'Lone suggests the following idea which sounds interesting to
  3. add as an optional mode of Cache_Lite class. 
  4. (still not tested in the Cache_Lite context)
  5.  
  6. -------------------------------------------------------------------------
  7. If you use the flags:
  8.  
  9. ignore_user_abort(true);
  10.  
  11. $fd = dio_open($szFilename, O_CREATE | O_EXCL | O_TRUNC | O_WRONLY,
  12. 0644);
  13. if (is_resource($fd)) {
  14.  
  15.    dio_fcntl($fd, F_SETLKW, array('type' => F_WRLCK));
  16.    dio_write($fd, $szBuffer);
  17.    dio_fcntl($fd, F_SETLK, array('type' => F_UNLCK));
  18.    dio_close($fd);
  19.  
  20. }
  21.  
  22. ignore_user_abort(false);
  23.  
  24. Only the first process will attempt to create a file. Additional
  25. processes will see that a file already exists (at the system level), and
  26. will fail. Another thing to note is that the file descriptor must be
  27. opened using dio_open(), and certain features, like fgets() won't work
  28. with it. If your just doing a raw write, dio_write() should be just
  29. fine. The dio_read() function should be used like:
  30.  
  31. $fd = dio_open($szFilename, O_RDONLY|O_NONBLOCK, 0644);
  32. if (is_resource($fd)) {
  33.  
  34.    dio_fcntl($fd, F_SETLKW, array('type' => F_RDLCK));
  35.    $szBuffer = dio_read($fd, filesize($szFilename));
  36.    dio_fcntl($fd, F_SETLK, array('type' => F_UNLCK));
  37.    dio_close($fd);
  38.  
  39. }
  40.  
  41. You still use locking to ensure that a write process can finish before
  42. another attempts to read the file. We also set non-blocking mode in read
  43. mode so that multiple readers can access the same resource at the same
  44. time. NOTE: Direct I/O support must be compiled into PHP for these
  45. features to work (--enable-dio).
  46. -------------------------------------------------------------------------
  47.  
  48.  
  49.  
  50. Another optionnal mode could be (Mike Benoit's interesting idea) :
  51. (not tested)
  52.  
  53. -------------------------------------------------------------------------
  54.         However recently I ran in to a problem with it and one of the projects
  55. I'm working on (http://phpgacl.sourceforge.net/). phpGACL caches _many_
  56. ( on the order of 10,000-100,000) very small pieces of data, when I
  57. tried using Cache Lite for this, my file system didn't like it much
  58. since there were so many files in a single directory. 
  59.  
  60. So I patched Cache Lite to support a hashed directory structure. ie:
  61.  
  62. <root cache dir>/<group>/<number between 0-999>/<chopped CRC32>
  63.  
  64. ../default
  65. ../default/081
  66. ../default/081/081162803
  67. ../default/215
  68. ../default/215/215106191
  69. ../default/333
  70. ../default/333/33376174
  71. ../default/366
  72. ../default/366/366703566
  73. ../default/500
  74.  
  75. I ran a few rough benchmarks, and this method was slower until the cache
  76. file numbers started growing to over 30,000 or so. Another advantage to
  77. doing it this way is it's really easy to clear the cache for a specific
  78. group. :)
  79.  
  80. The other change I made was to make it so cache data that was read from
  81. the file system was also stored in memory for subsequent reads. Scripts
  82. that actually do this should see quite a large increase in performance,
  83. if the script doesn't actually hit a cache entry more then once, it
  84. obviously slows things down slightly and uses more memory. Currently it
  85. ignores cache expire times when it stores data in memory, but in theory
  86. this shouldn't be a big deal.
  87.  
  88. <?
  89. /*
  90.  * phpGACL - Generic Access Control List - Hashed Directory Caching. 
  91.  * Copyright (c) 2002-2003 Mike Benoit
  92.  *
  93.  * This library is free software; you can redistribute it and/or
  94.  * modify it under the terms of the GNU Lesser General Public
  95.  * License as published by the Free Software Foundation; either
  96.  * version 2.1 of the License, or (at your option) any later version.
  97.  *
  98.  * This library is distributed in the hope that it will be useful,
  99.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  100.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  101.  * Lesser General Public License for more details.
  102.  *
  103.  * You should have received a copy of the GNU Lesser General Public
  104.  * License along with this library; if not, write to the Free Software
  105.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  106.  *
  107.  * For questions, help, comments, discussion, etc., please join the
  108.  * phpGACL mailing list. http://sourceforge.net/mail/?group_id=57103
  109.  *
  110.  * You may contact the author of phpGACL by e-mail at:
  111.  * ipso@snappymail.ca
  112.  *
  113.  * The latest version of phpGACL can be obtained from:
  114.  * http://phpgacl.sourceforge.net/
  115.  *
  116.  */
  117. require_once("Cache_Lite.php");
  118.  
  119. define('DIR_SEP', DIRECTORY_SEPARATOR);
  120.  
  121. class Hashed_Cache_Lite extends Cache_Lite
  122. {
  123.     /**
  124.     * Memory caching variable
  125.     * 
  126.     * @var array $_memoryCache
  127.     */
  128.     var $_memoryCache = NULL;
  129.  
  130.     /**
  131.     * Test if a cache is available and (if yes) return it - Original version by Fabien MARTY <fab@php.net>    
  132.     *
  133.     * @param string $id cache id
  134.     * @param string $group name of the cache group
  135.     * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
  136.     * @return string data of the cache (or false if no cache available)
  137.     * @access public
  138.     */
  139.     function get($id, $group = 'default', $doNotTestCacheValidity = false)
  140.     {
  141.         $this->_id = $id;
  142.         $this->_group = $group;
  143.  
  144.         if ($this->_caching) {
  145.             if ($this->_memoryCache[$group.'-'.$id]) {
  146.                 return ($this->_memoryCache[$group.'-'.$id]);
  147.             } else {
  148.                 $this->_setFileName($id, $group);
  149.                 if ($doNotTestCacheValidity) {
  150.                     if (file_exists($this->_file)) {
  151.                         $this->_memoryCache[$group.'-'.$id] = $this->_read();
  152.                         return ( ($this->_memoryCache[$group.'-'.$id]) );
  153.                     }
  154.                 } else {
  155.                     if (@filemtime($this->_file) > $this->_refreshTime) {
  156.                         $this->_memoryCache[$group.'-'.$id] = $this->_read();
  157.                         return ( ($this->_memoryCache[$group.'-'.$id]) );
  158.                     }
  159.                 }
  160.             }
  161.         }
  162.         return false;
  163.     }
  164.  
  165.     /**
  166.     * Make a file name (with path)
  167.     *
  168.     * @param string $id cache id
  169.     * @param string $group name of the group
  170.     * @access private
  171.     */
  172.     function _setFileName($id, $group)
  173.     {
  174.         //CRC32 with SUBSTR is still faster then MD5.
  175.         $encoded_id = substr(crc32($id),1);
  176.         //$encoded_id = md5($id);
  177.         
  178.         //Generate just the directory, so it can be created.
  179.         //Groups will have there own top level directory, for quick/easy purging of an entire group.
  180.         $dir = $this->_cacheDir.$group.'/'.substr($encoded_id,0,3);
  181.         $this->_create_dir_structure($dir);
  182.         
  183.         $this->_file = $dir.'/'.$encoded_id;
  184.     }
  185.  
  186.     /**
  187.     * Create full directory structure, Ripped straight from the Smarty Template engine.
  188.     * Version:     2.3.0
  189.     * Copyright:   2001,2002 ispi of Lincoln, Inc.
  190.     *
  191.     * @param string $dir Full directory.
  192.     * @access private
  193.     */
  194.     function _create_dir_structure($dir)
  195.     {
  196.         if (!@file_exists($dir)) {
  197.             $dir_parts = preg_split('!\\'.DIR_SEP.'+!', $dir, -1, PREG_SPLIT_NO_EMPTY);
  198.             $new_dir = ($dir{0} == DIR_SEP) ? DIR_SEP : '';
  199.             foreach ($dir_parts as $dir_part) {
  200.                 $new_dir .= $dir_part;
  201.                 if (!file_exists($new_dir) && !mkdir($new_dir, 0771)) {
  202.                     Cache_Lite::raiseError('Cache_Lite : problem creating directory \"$dir\" !', -3);   
  203.                     return false;
  204.                 }
  205.                 $new_dir .= DIR_SEP;
  206.             }
  207.         }
  208.     }
  209. }
  210.  
  211. ?>
  212. -------------------------------------------------------------------------
  213.